package com.firexxx;

import com.sun.tools.javac.code.Type;

import java.io.Serializable;
import java.lang.System;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.AbstractQueue;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;

public class GenericClassMain<T3, T4> {

    //泛型类
    class GenericClsBase<T1 extends String, T2> {
        //带泛型参数的方法
        public void setT(T1 t1, T2 t2) {
            t2 = null;
            System.out.println(t1);
        }
    }

    //这里的T3、T4是在定义泛型类型，而不会引用到GenericClassMain的泛型类型
    //这是由语法结构决定的，extends之后的符号才开始是实例化类型(也可以叫做引用类型)，因此即使GenericClassMain的T3 extends Integer也不会报错
//    class GenericClsBase111<T3 extends Integer, T4> {
//        //带泛型参数的方法
//        public void setT(T3 t1, T4 t2) {
//            t2 = null;
//            System.out.println(t1);
//        }
//    }

//    class GenericClsDerived11111<T3, T4> extends GenericClsBase {
//        //带泛型参数的方法
//        public void setT(String t1, Object t2) {
//            t2 = null;
//            System.out.println(t1);
//        }
//
////        public void setT1(T1 t1) {
////            t1 = null;
////        }
//    }

    //泛型派生类1
    class GenericClsDerived1 extends GenericClsBase {
        //带泛型参数的方法
        public void setT(String t1, Integer t2) {
            t2 = null;
            System.out.println(t1);
        }

//        public void setT1(T1 t1) {
//            t1 = null;
//        }
    }

    //泛型派生类1，extends后面带的泛型类型必须是可以已经定义过的，T3, T4会指向GenericClassMain泛型参数
    //这里的T3上界是Object，而GenericClsBase的第一个泛型要求的是String，因此两个泛型无法isSameType通过
//    class GenericClsDerived2 extends GenericClsBase<T3, T4> {
//        //带泛型参数的方法
//        public void setT(String t1, Integer t2) {
//            t2 = null;
//            System.out.println(t1);
//        }
//    }

    //泛型派生类2，T5，T6属于未在当前类(包括外部类)的env定义过的会报错
//    class GenericClsDerived3 extends GenericClsBase<T5, T6> {
//        //带泛型参数的方法
//        public void setT(String t1, Integer t2) {
//            t2 = null;
//            System.out.println(t1);
//        }
//    }

    //泛型派生类3
    class GenericClsDerived4<T1 extends String, T2> extends GenericClsBase {
        //带泛型参数的方法
        public void setT(String t1, Integer t2) {
            t2 = null;
            System.out.println(t1);
        }
    }

    class GenericClsDerived55 extends GenericClsBase<String, Integer> {
        //带泛型参数的方法
        public void setT(String t1, Integer t2) {
            t2 = null;
            System.out.println(t1);
        }
    }

    //泛型派生类4，GenericClsDerived5<T1 extends Integer, T2>会定义出T1、T2两个泛型类型，所以后面extends GenericClsBase<T1, T2>不会报错
    //但是由于类GenericClsDerived5定义的T1上界是Integer，而GenericClsBase要求的第一个泛型上界是String，因此会报错
//    class GenericClsDerived5<T1 extends Integer, T2> extends GenericClsBase<T1, T2> {
//        //带泛型参数的方法
//        public void setT(String t1, Integer t2) {
//            t2 = null;
//            System.out.println(t1);
//        }
//    }

    //GenericClsBase要求的第一个泛型上界是String，因此会报错
//    class GenericClsDerived6 extends GenericClsBase<Integer, Object> {
//        //带泛型参数的方法
//        public void setT(String t1, Integer t2) {
//            t2 = null;
//            System.out.println(t1);
//        }
//    }

    public void main(String[] args) {
        GenericClsDerived4 genericClsDerived4 = new GenericClsDerived4();
        genericClsDerived4.setT("1", "1");

//        //泛型类的实例化
//        GenericClsBase clsBaseNone = new GenericClsBase();
//        GenericClsBase clsBaseCorrect = new GenericClsBase<String, Integer>();
//        GenericClsBase clsBaseError = new GenericClsBase<Inetegr, Integer>();
//        GenericClsBase<String, Integer> clsBaseCorrect1 = new GenericClsBase();
//        GenericClsBase<Inetegr, Integer> clsBaseError1 = new GenericClsBase();
//        GenericClsBase<String, Integer> clsBaseCorrect2 = new GenericClsBase<String, Integer>();
//        GenericClsBase<Inetegr, Integer> clsBaseError2 = new GenericClsBase<Inetegr, Integer>();
//
//        //泛型类中带泛型参数的方法，正确
//        clsBaseNone.setT("1", "1");
//        //泛型类中带泛型参数的方法，错误
//        clsBaseNone.setT(1, "1");
//
//        //泛型派生类方法调用
//        GenericClsBase genericClsBase = new GenericClsDerived1();
//        genericClsBase.setT("1", "1");
//        genericClsBase = new GenericClsDerived2<String, Integer>();
//        genericClsBase.setT("1", "1");
//        genericClsBase = new GenericClsDerived3<String, Integer>();
//        genericClsBase.setT("1", "1");
//        genericClsBase = new GenericClsDerived4<String, Integer>();
//        genericClsBase.setT("1", "1");

//        GenericClsBase genericClsBase = new GenericClsBase<String, Integer>();
//        genericClsBase.fun1("1", "1");
    }
}
